﻿using IQReportes.Boundary;
using IQReportes.Models;
using IQReportes.Models.Logica;
using IQReportes.Utils;
using IQReportes.ViewModels;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Xml.Serialization;

namespace IQReportes.Controllers
{
    /// <summary>
    /// controller de panel de control
    /// </summary>
    public class PanelControlController : Controller
    {
        /// <summary>
        /// lógica de usuario
        /// </summary>
        LogicaUsuario logicaUsuario = new LogicaUsuario();
        /// <summary>
        /// lógica de perfil
        /// </summary>
        LogicaPerfil logicaPerfil = new LogicaPerfil();
        /// <summary>
        /// lógica de panel de control
        /// </summary>
        LogicaPanelDeControl logicaPanelControl = new LogicaPanelDeControl();
        /// <summary>
        /// formateador de datos 
        /// </summary>
        FormatterPanelControl formateador = new FormatterPanelControl();
        
        /// <summary>
        /// index de panel de control
        /// </summary>
        /// <returns>vista principal de panel de control</returns>
        public ActionResult Index()
        {
            if (!UsuarioController.usuarioConectado())
            {
                return (new UsuarioController()).Logout();
            }
            else
            {
                return View("Index", logicaUsuario.getUsuarioActualConf());
            }
        }
        /// <summary>
        /// obtener datos del módulo a partir de datos recibidos
        /// </summary>
        /// <param name="fechaInicial">fecha inicial</param>
        /// <param name="modulo">número de módulo</param>
        /// <param name="tipoChart">tipo de chart</param>
        /// <param name="institucion">institución seleccionada</param>
        /// <param name="nivelTreeHijo">nivel de nodo hijo seleccionado  del tree</param>
        /// <param name="nivelTreePadre">nivel de nodo padre del tree</param>
        /// <param name="codHijo">código de nodo hijo seleccionado del tree</param>
        /// <param name="codPadre">código de nodo padre del tree</param>
        /// <param name="motivoNoOperativo">motivo de no operación seleccionado</param>
        /// <param name="tiempoSinTx">tiempo sin transaccionar seleccionado</param>
        /// <param name="nivelTree">nivel del tree</param>
        /// <returns>datos del módulo requerido</returns>
        public ActionResult getData(string fechaInicial, int modulo,
                int tipoChart, int institucion, string nivelTreeHijo, string nivelTreePadre, string codHijo, string codPadre,
                string motivoNoOperativo, string tiempoSinTx, int nivelTree)
        {
            //string aux = fechaInicial + "|" + fechaFinal + "|" + modulo + "|" + tipoValorTree + "|" + tipoChart + "|" + institucion + "|" + puntoEquilibrio;
            ChartViewData dataVista = new ChartViewData();
            string cantidad = "";
            List<String[]> datos = null;
            QueryPCViewModel query = new QueryPCViewModel(fechaInicial, modulo, tipoChart, institucion, nivelTreeHijo,
                            nivelTreePadre, codHijo, codPadre, motivoNoOperativo, tiempoSinTx, nivelTree);

            string error = logicaPerfil.tienePermisoVerPC(modulo);
            if (error.Length > 0)
            {
                dataVista.error = error;
            }
            else
            {
                if (modulo == Constantes.MODULO1TREE)
                {
                    //consolidado = logicaTransaccion.obtenerConsolidadoTransacciones(query.antiguedad, query.codTablaTiempo, query.institucion);
                    List<TreeTransaccion> consolidado;
                    consolidado = logicaPanelControl.obtenerConsolidadoDirs(query.codTablaTiempo, query.institucion);

                    //return Json(getDataTree(query), JsonRequestBehavior.AllowGet);
                    //datos = getDataTree(query);
                    datos = FormatterPanelControl.consTreeToChartView(consolidado);
                }
                else if (modulo == Constantes.MODULO2MOTIVO)
                {
                    cantidad = "" + 200;
                    List<ConsolidadoRazon> consolidado;
                    consolidado = logicaPanelControl.obtenerConsolidadoRazones(query.codHijo, query.codPadre, query.nivel,
                                                                                query.institucion, query.idTiempoSinTx, tipoChart);
                    datos = FormatterPanelControl.consRazonesToChartView(consolidado, query.tipoChart);
                    //datos = getDataModulo(query);
                    //return Json(getDataModulo(query), JsonRequestBehavior.AllowGet);
                }
                else if (modulo == Constantes.MODULO3ANTIGUEDAD)
                {
                    cantidad = "" + 700;
                    List<ConsolidadoAntiguedad> consolidado;
                    consolidado = logicaPanelControl.obtenerConsolidadoAntiguedad(query.codHijo, query.codPadre, query.nivel,
                                                                                    query.institucion, query.idMotivoNoOperativo);
                    datos = FormatterPanelControl.consAntiguedadToChartView(consolidado, query.tipoChart);
                    //datos = getDataModulo(query);
                    //return Json(getDataModulo(query), JsonRequestBehavior.AllowGet);
                }
                else if (modulo == Constantes.MODULO4REPCOMERCIAL)
                {
                    cantidad = "" + 400;
                    List<DIR> consolidado;
                    consolidado = logicaPanelControl.obtenerRepComerciales(query.codHijo, query.codPadre, query.nivel,
                                                                           query.institucion, query.idMotivoNoOperativo,
                                                                           query.idTiempoSinTx);
                    datos = FormatterPanelControl.consRepresentantesToChartView(consolidado, query.tipoChart);
                    //datos = getDataModulo(query);
                    //return Json(getDataModulo(query), JsonRequestBehavior.AllowGet);
                }
            }
            dataVista.cantidadTotal = cantidad;
            dataVista.datos = datos;
            return Json(dataVista, JsonRequestBehavior.AllowGet);
        }

        /// <summary>
        /// convertir vista a string
        /// </summary>
        /// <param name="viewName">nombre de la vista</param>
        /// <param name="model">datos para enviar a la vista</param>
        /// <returns>string con la vista generada con el model recibido</returns>
        protected string RenderPartialViewToString(string viewName, object model)
        {
            if (string.IsNullOrEmpty(viewName))
                viewName = ControllerContext.RouteData.GetRequiredString("action");

            ViewData.Model = model;

            using (StringWriter sw = new StringWriter())
            {
                ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
                ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
                viewResult.View.Render(viewContext, sw);
                return sw.GetStringBuilder().ToString();
            }
        }
        /// <summary>
        /// descargar datos del módulo a partir de datos recibidos
        /// </summary>
        /// <param name="fechaInicial">fecha inicial</param>
        /// <param name="modulo">número de módulo</param>
        /// <param name="tipoChart">tipo de chart</param>
        /// <param name="institucion">institución seleccionada</param>
        /// <param name="nivelTreeHijo">nivel de nodo hijo seleccionado  del tree</param>
        /// <param name="nivelTreePadre">nivel de nodo padre del tree</param>
        /// <param name="codHijo">código de nodo hijo seleccionado del tree</param>
        /// <param name="codPadre">código de nodo padre del tree</param>
        /// <param name="motivoNoOperativo">motivo de no operación seleccionado</param>
        /// <param name="tiempoSinTx">tiempo sin transaccionar seleccionado</param>
        /// <param name="nivelTree">nivel del tree</param>
        /// <returns>archivo excel con los datos del módulo requerido</returns>
        public ActionResult Download(string fechaInicial, int modulo,
                int tipoChart, int institucion, string nivelTreeHijo,
                string nivelTreePadre, string codHijo, string codPadre,
                string motivoNoOperativo, string tiempoSinTx, int nivelTree)
        {

            QueryPCViewModel query = new QueryPCViewModel(fechaInicial, modulo, tipoChart, institucion, nivelTreeHijo,
                            nivelTreePadre, codHijo, codPadre, motivoNoOperativo, tiempoSinTx, nivelTree);

            List<String[]> datos = new List<string[]>();

                if (modulo == Constantes.MODULO2MOTIVO)
                {
                
                    List<ConsolidadoRazon> consolidado;
                    consolidado = logicaPanelControl.obtenerConsolidadoRazones(query.codHijo, query.codPadre, query.nivel,
                                                                                query.institucion, query.idTiempoSinTx, tipoChart);
                    datos = FormatterPanelControl.consRazonesToChartView(consolidado, query.tipoChart);
                    
                }
                else if (modulo == Constantes.MODULO3ANTIGUEDAD)
                {
                    
                    List<ConsolidadoAntiguedad> consolidado;
                    consolidado = logicaPanelControl.obtenerConsolidadoAntiguedad(query.codHijo, query.codPadre, query.nivel,
                                                                                    query.institucion, query.idMotivoNoOperativo);
                    datos = FormatterPanelControl.consAntiguedadToChartView(consolidado, Constantes.COLUMNCHART);
                    
                }
                else if (modulo == Constantes.MODULO4REPCOMERCIAL)
                {
                    
                    List<DIR> consolidado;
                    consolidado = logicaPanelControl.obtenerRepComerciales(query.codHijo, query.codPadre, query.nivel,
                                                                           query.institucion, query.idMotivoNoOperativo,
                                                                           query.idTiempoSinTx);
                    datos = FormatterPanelControl.consRepresentantesToChartView(consolidado, query.tipoChart);
                    
                }


            //gg.Add(new String[] { "H1", "H2" });
            //gg.Add(new String[] { "D1", "D2" });
            //gg.Add(new String[] { "d1", "d2" });
            //gg.Add(new String[] { "f1", "f2" });

            string html = RenderPartialViewToString("PartialViewName", datos);
            // if your view don't have any model then you can pass as null

            html = html.Replace("\n", "");
            html = html.Replace("\r", "");
            html = html.Replace("  ", "");

            return new DownloadFileActionResult(html, "ExcelSheetName.xls");
        }

        #region DataPrueba
        private List<String[]> getDataPie(string ff)
        {
            List<String[]> aux = new List<String[]>();
            aux.Add(new String[] { "string", "number" });//tipo cabeceras
            aux.Add(new String[] { "Topping", "Slices" });//nombre cabeceras
            aux.Add(new String[] { ff, "3" });
            aux.Add(new String[] { "Depósitos", "7" });
            aux.Add(new String[] { "Recargas ñ", "3" });
            aux.Add(new String[] { "Pagos", "4" });
            aux.Add(new String[] { "Retiros", "2" });
            return aux;
        }


        private List<String[]> getDataColumn(string ff)
        {
            List<String[]> aux = new List<String[]>();
            aux.Add(new String[] { "string", "number", "number", "number", "number" });//tipo cabeceras
            aux.Add(new String[] { "Year", "1D", "2D", "3D", "4D" });//nombre cabeceras
            aux.Add(new String[] { "24/07/2013", "1336060", "3817614", "974066", "21104797" });

            return aux;
        }
        private List<String[]> getDataLine(string ff)
        {
            List<String[]> aux = new List<String[]>();
            aux.Add(new String[] { "string", "number", "number", "number", "number" });//tipo cabeceras
            aux.Add(new String[] { "X", "Aprobada", "Trunca", "Por imprimir", "Exitosa" });//nombre cabeceras
            aux.Add(new String[] { "10/07/2013", "123", "12", "50", "30" });
            aux.Add(new String[] { "17/07/2013", "10", "100", "50", "20" });
            aux.Add(new String[] { "24/07/2013", "30", "1", "1000", "10" });
            return aux;
        }
        private List<String[]> getDataTable(string ff)
        {
            List<String[]> aux = new List<String[]>();
            aux.Add(new String[] { "string", "number", "number", "number", "number" });//tipo cabeceras
            aux.Add(new String[] { "tablaCol1", "#TX", "Cargos", "Abonos", "Total" });//nombre cabeceras
            for (int i = 0; i < 30; i++)
            {
                aux.Add(new String[] { "24/07/2013", "40", "400", "200", "" + (200 + i) });
            }
            return aux;
        }

        private List<String[]> getDataModulo(QueryPCViewModel query)
        {
            //return getDataPie(query.tipoChart + "");
            var aux = query.tipoChart + "";
            if (query.tipoChart == Constantes.PIECHART)
                return getDataPie(aux + query.fechaInicial + "|" + query.nivelTreeHijo + "|" + query.nivelTreePadre + "|" + query.motivoNoOperativo + "|" +
                    query.tiempoSinTx + "|" + query.modulo);
            if (query.tipoChart == Constantes.COLUMNCHART)
                return getDataColumn(aux);
            if (query.tipoChart == Constantes.LINECHART)
                return getDataLine(aux);
            return getDataTable(aux);
        }

        public List<String[]> getDataTree(QueryPCViewModel query)
        {
            string parametro = "Perú ";
            List<String[]> aux = new List<String[]>();

            aux.Add(new String[] { "string", "string", "number", "number", "string", "string" });
            aux.Add(new String[] { "Location", "Parent", "Market trade volume (size)", "Market increase/decrease (color)", "codHijo", "codPadre" });
            aux.Add(new String[] { "Lima", parametro, "0", "0", "hijo1", "cod1" });
            aux.Add(new String[] { "Anchash", parametro, "0", "0", "hijo2", "cod1" });
            aux.Add(new String[] { "Arequipa", parametro, "0", "0", "hijo3", "cod1" });
            aux.Add(new String[] { "Ica", parametro, "0", "0", "hijo4", "cod1" });
            aux.Add(new String[] { "Puno", parametro, "0", "0", "hijo5", "cod1" });
            aux.Add(new String[] { "Prov 1", "Lima", "11", "10", "codgg-1", "hijo1" });
            int max = 127;

            for (int i = 0; i < max; i++)
            {
                aux.Add(new String[] { "Prov " + (i + 2), "Lima", "0", "0", "codgg" + i, "hijo1" });
                for (int j = 0; j < 10; j++)
                {
                    aux.Add(new String[] { "Dis" + i + j, "Prov " + (i + 2), "0", "0", "codff" + j, "codgg" + i });
                    for (int z = 0; z < 10; z++)
                    {
                        aux.Add(new String[] { "Local" + z + i + j, "Dis" + i + j, "52", "31", "codhh" + z, "codff" + j });
                    }
                }
            }
            aux.Add(new String[] { parametro, null, "0", "0", "cod1", null });

            return aux;
        }
        #endregion
    }
}
